import json

from QQLoginTool.QQtool import OAuthQQ
from django.contrib.auth import login
from django.http import JsonResponse
from django.shortcuts import render

from apps.oauth.models import OAuthQQUser
from apps.users.models import User
from meiduo_mall import settings

# Create your views here.
from django.views import View

from utils.add_secret import generic_openid, check_access_token

"""
第三方登录步骤：
    1. 注册成为开发者
    2. 创建应用
    3. 按照文档开发

        3.1 准备工作

            # QQ登录参数
            # 我们申请的 客户端id
            QQ_CLIENT_ID = '101474184'        appid
            # 我们申请的 客户端秘钥
            QQ_CLIENT_SECRET = 'c6ce949e04e12ecc909ae6a8b09b637c'       appkey
            # 我们申请时添加的: 登录成功后回调的路径
            QQ_REDIRECT_URI = 'http://www.meiduo.site:8080/oauth_callback.html'
        3.2 放置qq登录的图标

        3.3 根据oauth2.0获取code和token
            1.获取code
            2.使用code向QQ服务器请求access_token

        3.4 使用access_token向QQ服务器请求openid
            OpenID是此网站上或应用中唯一对应用户身份的标识，网站或应用可将此ID进行存储，便于用户下次登录时辨识其身份，或将其与用户在网站上或应用中的原有账号进行绑定。

        把openid和用户信息进行一一对应的绑定

生成用户绑定链接======> 获取code==========> 获取token============> 获取openid ===============> 保存openid和对应用户信息
"""

# 生成用户绑定链接
"""
前端：
    当用户点击qq登录图标的时候，前端应该发送一个axios请求
后端：
    请求：
    业务逻辑：
        调用qqlogintool生成跳转链接
    响应：
        返回跳转链接{'code': 0, 'errmsg': 'ok'}
    路由：
        GET qq/authorization
    步骤：
        # 1.生成qqlogintool实例对象
        # 2.调用对象方法，生成跳转链接
        # 3.返回响应
"""


class QQLoginView(View):

    def get(self, request):
        # 1.生成qqlogintool实例对象
        qq = OAuthQQ(client_id=settings.QQ_CLIENT_ID,  # APPID
                     client_secret=settings.QQ_CLIENT_SECRET,  # APPSECRET
                     redirect_uri=settings.QQ_REDIRECT_URI,  # 回跳页面
                     state="XXXX")  # 状态码

        # 2.调用对象方法，生成跳转链接
        qq_login_url = qq.get_qq_url()

        # 3.返回响应
        return JsonResponse({'code': 0, 'errmsg': 'ok', 'login_url': qq_login_url})


"""
需求：获取code，通过code获取token，再通过token换区openid
前端：
    前端获取用户同意的code，将这个code发送给后端
后端：
    请求： 获取code
    业务逻辑：
        通过code换取token，再通过token换取openid
        根据openid进行判断
        如果没有绑定过则需要绑定
        如果绑定过则直接登录
    
    响应：
    路由：
        GET oauth_callback/
        
    步骤：
        # 1.获取code
        # 2.通过code换取token
        # 3.通过token换取openid
        # 4.根据openid进行判断
        # 5.如果没有绑定过则需要登录
        # 6.如果绑定过，则直接登录        
"""


class OAuthQQView(View):

    def get(self, request):
        # 1.获取code
        code = request.GET.get('code')
        if code is None:
            return JsonResponse({'code': 400, 'errmsg': '参数不全'})

        # 2.通过code换取token
        qq = OAuthQQ(client_id=settings.QQ_CLIENT_ID,  # APPID
                     client_secret=settings.QQ_CLIENT_SECRET,  # APPSECRET
                     redirect_uri=settings.QQ_REDIRECT_URI,  # 回跳页面
                     state="XXXX")  # 状态码

        # 3.通过token换取openid
        token = qq.get_access_token(code)
        # '85BD8CB79C9BD25FF2A6B2974EAA7E04'
        openid = qq.get_open_id(token)

        # 4.根据openid进行判断
        try:
            qquser = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 不存在
            # 对openid进行加密
            access_token = generic_openid(openid)
            response = JsonResponse({'code': 400, 'access_token': access_token})
            return response

        else:
            # 存在
            # 6.如果绑定过，则直接登录
            # 6.1 设置session
            login(request, qquser.user)
            # 6.2 设置cookie
            response = JsonResponse({'code': 0, 'errmsg': 'ok'})

            response.set_cookie('username', qquser.user.username)

            return response

    def post(self, request):
        # 1. 接受请求
        data = json.loads(request.body.decode())

        # 2.获取请求参数 openid
        mobile = data.get('mobile')
        password = data.get('password')
        sms_code = data.get('sms_code')
        access_token = data.get('access_token')
        openid = check_access_token(access_token)

        if openid is None:
            return JsonResponse({'code': 400, "errmsg": '参数不全'})
        # 获取数据后需要对数据进行验证

        # 3.根据手机号进行用户查询
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            # # 5.查询到手机号没有注册，我们就创建一个user信息，然后再绑定
            user = User.objects.create_user(username=mobile, mobile=mobile, password=password)

        else:
            # # 4.查询到用户手机号已经注册，判断密码是否正确。就可以直接绑定和openid信息
            if not user.check_password(password):
                return JsonResponse({'code': 400, 'errmsg': '账号或密码错误'})

        OAuthQQUser.objects.create(user=user, openid=openid)

        # 6.状态保持
        login(request, user)

        # 7.返回响应
        response = JsonResponse({'code': 0, 'errmsg': 'ok'})

        response.set_cookie('username', user.username)

        return response


# 绑定账号信息
"""
前端：
    当用户输入手机号，密码，短信验证码之后发送axios请求。请求需要携带mobile，password，sms_code，access_token
后端：
    请求：
        接受请求，获取相关参数
    业务逻辑：
        绑定，完成状态保持
        
    响应：
        返回code=0，跳转到首页
    路由：
        POST
    
    步骤：
        # 1. 接受请求
        # 2.获取请求参数 openid
        # 3.根据手机号进行用户查询
        # 4.查询到用户手机号已经注册，就可以直接绑定和openid信息
        # 5.查询到手机号没有注册，我们就创建一个user信息，然后再绑定
        # 6.状态保持
        # 7.返回响应
"""
